package com.earthea.common.io.excel;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.earthea.common.io.excel.listener.CustomSheetReader;
import com.earthea.common.io.excel.listener.ISheetReader;
import com.earthea.common.io.excel.writer.CustomSheetWriter;
import com.earthea.common.io.excel.writer.DefaultWriterHandler;
import com.earthea.common.io.excel.writer.ISheetWriter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static java.util.stream.Collectors.groupingBy;

/**
 * Excel读写工具类
 */
public class ExcelUtils {
    /**
     * 默认Excel输出格式
     */
    private static final DefaultWriterHandler DEFAULT_WRITER_HANDLER = new DefaultWriterHandler();

    /**
     * 读多个sheet
     *
     * @param sheetReaders sheet读列表
     */
    public static void read(List<? extends ISheetReader> sheetReaders) {
        sheetReaders.stream().collect(groupingBy(ISheetReader::getExcelName)).forEach((key, value) -> read(key, value));
    }

    /**
     * 读一个sheet
     *
     * @param sheetReader sheet
     */
    public static void read(ISheetReader sheetReader) {
        List<ISheetReader> sheetReaders = new ArrayList<>();
        sheetReaders.add(sheetReader);
        read(sheetReaders);
    }

    private static void read(String excelName, List<? extends ISheetReader> sheetReaders) {
        for (ISheetReader sheetReader : sheetReaders) {
            EasyExcel.read(excelName, sheetReader.getClazz(), sheetReader).extraRead(CellExtraTypeEnum.HYPERLINK).extraRead(CellExtraTypeEnum.MERGE).sheet(sheetReader.getSheetName()).doRead();
        }
    }

    public static <T> List<T> read(CustomSheetReader<T> sheetReader) {
        EasyExcel.read(sheetReader.getExcelName(), sheetReader.getClazz(), sheetReader).extraRead(CellExtraTypeEnum.HYPERLINK).extraRead(CellExtraTypeEnum.MERGE).sheet(sheetReader.getSheetName()).doRead();
        return sheetReader.getDataList();
    }

    public static <T> List<T> read(String excelName, String sheetName, Class<T> clazz) {
        return read(new CustomSheetReader<>(excelName, sheetName, clazz));
    }

    /**
     * 写多个sheet
     *
     * @param sheetWriters sheet写列表
     */
    public static void write(List<? extends ISheetWriter> sheetWriters) {
        write(sheetWriters, null);
    }

    /**
     * 写多个sheet
     *
     * @param sheetWriters sheet写列表
     * @param writeHandler 输出格式
     */
    public static void write(List<? extends ISheetWriter> sheetWriters, WriteHandler writeHandler) {
        sheetWriters.stream().collect(groupingBy(ISheetWriter::getExcelName)).forEach((key, value) -> write(key, value, writeHandler));
    }

    /**
     * 写一个sheet
     *
     * @param sheetWriter sheet
     */
    public static void write(ISheetWriter sheetWriter) {
        write(sheetWriter, null);
    }

    /**
     * 写一个sheet
     *
     * @param sheetWriter  sheet
     * @param writeHandler 输出格式
     */
    public static void write(ISheetWriter sheetWriter, WriteHandler writeHandler) {
        List<ISheetWriter> sheetWriters = new ArrayList<>();
        sheetWriters.add(sheetWriter);
        write(sheetWriters, writeHandler);
    }

    private static void write(String excelName, List<? extends ISheetWriter> sheetWriters, WriteHandler writeHandler) {
        if (writeHandler == null) {
            writeHandler = DEFAULT_WRITER_HANDLER;
        }
        ExcelWriter excelWriter = EasyExcel.write(excelName).registerWriteHandler(writeHandler).build();
        for (ISheetWriter sheetWriter : sheetWriters) {
            WriteSheet writeSheet = EasyExcel.writerSheet(sheetWriter.getSheetNo(), sheetWriter.getSheetName()).needHead(false).build();
            WriteTable writeTable = EasyExcel.writerTable(0).needHead(true).head(sheetWriter.getClazz()).build();
            excelWriter.write(sheetWriter.getDataList(), writeSheet, writeTable);
        }
        excelWriter.finish();
    }

    public static <T> void write(CustomSheetWriter<T> customSheetWriter) {
        write(customSheetWriter.getExcelName(), customSheetWriter.getSheetName(), customSheetWriter.getDataList(), customSheetWriter.getClazz());
    }

    public static <T> void write(String excelName, String sheetName, Collection<T> dataList, Class<T> clazz) {
        ExcelWriter excelWriter = EasyExcel.write(excelName).registerWriteHandler(DEFAULT_WRITER_HANDLER).build();
        WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).needHead(false).build();
        WriteTable writeTable = EasyExcel.writerTable(0).needHead(true).head(clazz).build();
        excelWriter.write(dataList, writeSheet, writeTable);
        excelWriter.finish();
    }
}
